package com.yalu.read.pdf.purchase;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.yalu.entity.PurchaseData;
import lombok.val;
import org.apache.pdfbox.io.RandomAccessFile;
import org.apache.pdfbox.pdfparser.PDFParser;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.springframework.beans.BeanUtils;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class PurchaseTenOneRead {

    /**
     * 测试pdf文件的创建
     *
     * @param args
     */
    public static void main(String[] args) {
        String filePath = "D://yalu//purchase//";  //这里先手动把绝对路径的文件夹给补上。
        List<String> filePaths = new ArrayList<>();
        recursionFile(filePath, filePaths);
        System.out.println("文件数量：" + filePaths.size());
        List<PurchaseData> list = new ArrayList<>();
        String year = filePath.replaceAll("D://yalu//", "").replaceAll("//", "");
        System.out.println(year);
        for (String fileName : filePaths) {
            final val isFail = readPdf(fileName, list);
            if (isFail) {
                PurchaseData purchaseData = new PurchaseData();
                purchaseData.setFileName(fileName);
                list.add(purchaseData);
            }
        }
        String outFileName = "D:\\yalu\\采购单" + System.currentTimeMillis() + ".xlsx";
        writerFils(list, outFileName);
        System.out.println("文件总数：" + filePaths.size() + " 数据总数：" + list.size());
    }

    /**
     * 读PDF文件，使用了pdfbox开源项目
     *
     * @param fileName
     */
    public static boolean readPdf(String fileName, List<PurchaseData> list) {
        File file = new File(fileName);
        FileInputStream in = null;
        boolean isWanCheng = true;
        try {
            in = new FileInputStream(fileName);
            // 新建一个PDF解析器对象
            PDFParser parser = new PDFParser(new RandomAccessFile(file, "r"));
            // 对PDF文件进行解析
            parser.parse();
            // 获取解析后得到的PDF文档对象
            PDDocument pdfdocument = parser.getPDDocument();
            int pageSize = pdfdocument.getNumberOfPages();
            Queue<PurchaseData> dataQueue = new LinkedList<>();
            for (int i = 0; i < pageSize; i++) {
                // 新建一个PDF文本剥离器
                PDFTextStripper stripper = new PDFTextStripper();
                // 设置按顺序输出
                stripper.setSortByPosition(true);
                stripper.setStartPage(i + 1);
                stripper.setEndPage(i + 1);
                String lineSepartor = stripper.getLineSeparator();
                // 从PDF文档对象中剥离文本
                String result = stripper.getText(pdfdocument);
                String[] resultArray = result.split(lineSepartor);
                int arrayLength = resultArray.length;
                for (int y = 0; y < arrayLength; y++) {
                    PurchaseData dataNow = dataQueue.poll();
                    PurchaseData purchaseData = new PurchaseData();
                    if (null != dataNow) {
                        BeanUtils.copyProperties(dataNow, purchaseData);
                    }
                    String lineText = resultArray[y];

                    if (StringUtils.hasText(lineText) && lineText.contains("Invoice No.：")) {
                        final val split = lineText.split("：");
                        final val no = split[2];
                        purchaseData.setPurchaseNo(StringUtils.hasText(no) ? no.trim() : null);
                        dataQueue.offer(purchaseData);
                    } else if (StringUtils.hasText(lineText) && lineText.contains("P/I NO :")) {
                        final val split = lineText.split(":");
                        final val date = split[1];
                        final val no = split[2];
                        purchaseData.setDate(StringUtils.hasText(date) ? date.replace("Invoice No.", "").trim() : null);
                        purchaseData.setPurchaseNo(StringUtils.hasText(no) ? no.trim() : null);
                        dataQueue.offer(purchaseData);
                    } else if (StringUtils.hasText(lineText) && lineText.contains("TO：")) {
                        final val split = lineText.split("TO：");
                        final val date = split[1];
                        purchaseData.setPurchaseName(StringUtils.hasText(date) ? date.replace("备注", "").trim() : null);
                        dataQueue.offer(purchaseData);
                    } else if (StringUtils.hasText(lineText) && lineText.contains("Invoice No.")) {
                        final val split = lineText.split(":");
                        final val date = split[1];
                        final val no = split[2];
                        purchaseData.setDate(StringUtils.hasText(date) ? date.replace("Invoice No.", "").trim() : null);
                        purchaseData.setPurchaseNo(StringUtils.hasText(no) ? no.trim() : null);
                        dataQueue.offer(purchaseData);
                    } else if (StringUtils.hasText(lineText) && lineText.contains("Invocie")) {
                        final val split = lineText.split(" ");
                        final val no = split[1];
                        purchaseData.setPurchaseNo(StringUtils.hasText(no) ? no.trim() : null);
                        dataQueue.offer(purchaseData);
                    } else if (StringUtils.hasText(lineText) && lineText.contains("出货单号：")) {
                        final val split = lineText.split("：");
                        final val name = split[1];
                        final val no = split[2];
                        purchaseData.setPurchaseName(StringUtils.hasText(name) ? name.replace("出货单号","").trim() : null);
                        purchaseData.setPurchaseNo(StringUtils.hasText(no) ? no.trim() : null);
                        dataQueue.offer(purchaseData);
                    } else if (StringUtils.hasText(lineText) && lineText.contains("PI No.：")) {
                        final val split = lineText.split("：");
                        final val no = split[1];
                        purchaseData.setPurchaseNo(StringUtils.hasText(no) ? no.trim() : null);
                        dataQueue.offer(purchaseData);
                    } else if (StringUtils.hasText(lineText) && lineText.contains("PI No.")) {
                        final val split = lineText.split(":");
                        final val no = split[1];
                        purchaseData.setPurchaseNo(StringUtils.hasText(no) ? no.trim() : null);
                        dataQueue.offer(purchaseData);
                    } else if (StringUtils.hasText(lineText) && lineText.contains("P/INO :")) {
                        final val split = lineText.split(":");
                        final val date = split[1];
                        final val no = split[2];
                        purchaseData.setDate(StringUtils.hasText(date) ? date.replace("DATE", "").trim() : null);
                        purchaseData.setPurchaseNo(StringUtils.hasText(no) ? no.trim() : null);
                        dataQueue.offer(purchaseData);
                    } else if (StringUtils.hasText(lineText) && lineText.contains("Date：")) {
                        final val split = lineText.split("：");
                        final val date = split[2];
                        purchaseData.setDate(StringUtils.hasText(date) ? date.replace("DATE", "").trim() : null);
                        dataQueue.offer(purchaseData);
                    } else if (StringUtils.hasText(lineText) && lineText.contains("Issue Date:")) {
                        final val split = lineText.split(":");
                        final val date = split[1];
                        purchaseData.setDate(StringUtils.hasText(date) ? date.replace("DATE", "").trim() : null);
                        dataQueue.offer(purchaseData);
                    } else if (StringUtils.hasText(lineText) && lineText.contains("DATE.：")) {
                        final val split = lineText.split("：");
                        final val date = split[1];
                        purchaseData.setDate(StringUtils.hasText(date) ? date.replace("DATE", "").trim() : null);
                        dataQueue.offer(purchaseData);
                    } else if (StringUtils.hasText(lineText) && lineText.contains("DATE.")) {
                        final val split = lineText.split(":");
                        final val date = split[1];
                        purchaseData.setDate(StringUtils.hasText(date) ? date.replace("DATE", "").trim() : null);
                        dataQueue.offer(purchaseData);
                    } else if (StringUtils.hasText(lineText) && lineText.contains("DATE: ")) {
                        final val split = lineText.split("DATE: ");
                        final val date = split[1];
                        purchaseData.setDate(StringUtils.hasText(date) ? date.trim() : null);
                        dataQueue.offer(purchaseData);
                    } else if (StringUtils.hasText(lineText) && lineText.contains("出货日期：")) {
                        final val split = lineText.split("出货日期：");
                        final val date = split[1];
                        purchaseData.setDate(StringUtils.hasText(date) ? date.trim() : null);
                        purchaseData.setAmount("不知道");
                        dataQueue.offer(purchaseData);
                    } else if (StringUtils.hasText(lineText) && lineText.contains("INVOICE NO:")) {
                        final val split = resultArray[y + 1].split(" ");
                        final val date = resultArray[y + 3];
                        final val no = split[split.length - 1];
                        purchaseData.setDate(StringUtils.hasText(date) ? date.replace("DATE", "").trim() : null);
                        purchaseData.setPurchaseNo(StringUtils.hasText(no) ? no.trim() : null);
                        dataQueue.offer(purchaseData);
                    } else if (y == 1) {
                        purchaseData.setPurchaseName(lineText);
                        dataQueue.offer(purchaseData);
                    } else if (StringUtils.hasText(lineText) && lineText.contains("Total Amount:")) {
                        String[] lineArray = lineText.split(" ");
                        String amount = lineArray[lineArray.length - 1].trim();
                        String total = lineArray[lineArray.length - 2].trim();
                        purchaseData.setAmount(amount);
                        purchaseData.setTotal(total);
                        dataQueue.offer(purchaseData);
                    } else if (StringUtils.hasText(lineText) && lineText.contains("Total Amount ")) {
                        String[] lineArray = lineText.split(" ");
                        String amount = lineArray[lineArray.length - 1].trim();
                        purchaseData.setAmount(amount);
                        dataQueue.offer(purchaseData);
                    } else if (StringUtils.hasText(lineText) && lineText.contains("Amount：")) {
                        String[] lineArray = lineText.split("：");
                        String line = lineArray[1].trim();
                        purchaseData.setAmount(line);
                        dataQueue.offer(purchaseData);
                    } else if (StringUtils.hasText(lineText) && lineText.contains("TOTAL:")) {
                        String[] lineArray = lineText.split(" ");
                        if (lineArray.length == 5) {
                            String amount = lineArray[lineArray.length - 1].trim();
                            String currency = lineArray[lineArray.length - 2].trim();
                            String total = lineArray[1].trim();
                            purchaseData.setAmount(amount);
                            purchaseData.setTotal(total);
                            purchaseData.setCurrency(currency);
                            dataQueue.offer(purchaseData);
                        } else {
                            lineArray = lineText.split(":");
                            String line = lineArray[1].trim();
                            purchaseData.setAmount(line);
                            dataQueue.offer(purchaseData);
                        }
                    } else {
                        dataQueue.offer(purchaseData);
                    }
                    if (StringUtils.hasText(purchaseData.getAmount()) && StringUtils.hasText(purchaseData.getPurchaseNo()) && StringUtils.hasText(purchaseData.getDate())) {
                        purchaseData.setFileName(fileName);
                        list.add(purchaseData);
                        dataQueue.poll();
                        isWanCheng = false;
                        break;
                    }
                }
            }
            pdfdocument.close();
        } catch (Exception e) {
            System.out.println("读取PDF文件" + file.getAbsolutePath() + "生失败！" + e);
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
        return isWanCheng;
    }

    /**
     * 写入文件
     *
     * @param data
     * @param outFileName
     */
    public static void writerFils(List<PurchaseData> data, String outFileName) {
        try {
            ExcelWriter excelWriter = EasyExcel.write(outFileName, PurchaseData.class).build();
            String sheetName = "1";
            List<PurchaseData> list = new ArrayList<>(data.size());
            for (PurchaseData purchaseData : data) {
                PurchaseData billDetailDataExcel = new PurchaseData();
                BeanUtils.copyProperties(purchaseData, billDetailDataExcel);
                list.add(billDetailDataExcel);
            }
            WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).build();
            excelWriter.write(list, writeSheet);

            // 千万别忘记finish 会帮忙关闭流
            excelWriter.finish();
        } catch (Exception e) {
            System.out.println("文件写入失败：" + e.getMessage());
        }
    }

    /**
     * 递归文件
     *
     * @param path
     * @param filePaths
     */
    public static void recursionFile(String path, List<String> filePaths) {
        if (StringUtils.hasText(path)) {
            File file = new File(path);
            for (File f : file.listFiles()) {
                if (f.isDirectory()) {
                    recursionFile(f.getPath(), filePaths);
                } else {
                    if (f.getPath().contains(".pdf")) {
                        filePaths.add(f.getPath());
                    }
                }
            }
        }
    }
}
